package com.train.mgr.modules.biz.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.train.common.enums.FileTypeEnum;
import com.train.common.exception.BusinessException;
import com.train.common.utils.AuthUtils;
import com.train.common.utils.FileUtils;
import com.train.common.utils.ToolUtil;
import com.train.mgr.modules.biz.dto.response.FileDto;
import com.train.mgr.modules.biz.entity.FileUpload;
import com.train.mgr.modules.biz.mapper.FileUploadMapper;
import com.train.mgr.modules.biz.service.IFileUploadService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.UUID;

/**
 * 文件实体表 服务实现类
 *
 * @author cxg
 * @date 2021/11/02 11:28
 */
@Slf4j
@Service
public class FileUploadServiceImpl extends ServiceImpl<FileUploadMapper, FileUpload> implements IFileUploadService {

    @Value("${file.upload-support-ext}")
    private String SUPPORT_EXT;

    @Value("${file.upload-folder}")
    private String uploadFolder;

    @Override
    public FileDto uploadLocal(MultipartFile file, String busiType){
        InputStream inputStream = null;
        FileInputStream fi = null;
        String fileMd5 = "";
        String fileName = file.getOriginalFilename();
        String contentType = file.getContentType();
        FileTypeEnum fileTypeNum = FileTypeEnum.parseContentType(contentType);
        String fileType = ObjectUtil.isNull(fileTypeNum) ? "" : fileTypeNum.toString();
        String extension = FilenameUtils.getExtension(fileName);
        log.info("realFileName:{}",fileName);
        if(StrUtil.isBlank(fileType)){
            if ("png".equalsIgnoreCase(extension) || "jpg".equalsIgnoreCase(extension) || "jpeg".equalsIgnoreCase(extension)){
                fileType = FileTypeEnum.IMAGE.toString();
            }
            if ("mp4".equalsIgnoreCase(extension)){
                fileType = FileTypeEnum.VIDEO.toString();
            }
        }
        if (StrUtil.isEmpty(extension) || !extension.toLowerCase().matches(SUPPORT_EXT)) {
            throw new BusinessException( "不允许上传的文件格式，请上传指定文件：doc,docx,pdf,ppt");
        }

        try{
            inputStream = file.getInputStream();
            // 文件md5计算
            fileMd5 = FileUtils.fileMD5(inputStream);

            long fileSizes = file.getSize();
            DecimalFormat df = new DecimalFormat("#.00");
            double fileSizeUnitKb = Double.parseDouble(df.format((double)fileSizes/1024));
            log.info("文件原始大小:{} B, {}KB",fileSizes,fileSizeUnitKb);
            String newFileName = genarateNewFileName(fileName);
            String newPdfFileName = getNameWithoutExtension(newFileName)+".pdf";
            log.info("newFileName:{}",newFileName);

            String uploadFileDir=  uploadFolder+"/files/"+ ToolUtil.dateToStrYMD(new Date())+"/";
            File destFileDir = new File(uploadFileDir);
            if(!destFileDir.exists()){
               destFileDir.mkdirs();
            }
            String visitFileUrl = String.format("/files/%s/%s",ToolUtil.dateToStrYMD(new Date()), newFileName);
            String destFilePath = uploadFileDir + newFileName;
            String visitPdfFileUrl = String.format("/files/%s/%s",ToolUtil.dateToStrYMD(new Date()), newPdfFileName);

            File destFile = new File(destFilePath);
            //调用transferTo将上传的文件保存到指定的地址
            file.transferTo(destFile);

            FileUpload fileUpload = new FileUpload();
            fileUpload.setFileContentType(fileType);
            fileUpload.setFileMd5(fileMd5);
            fileUpload.setFileExtension(extension);
            fileUpload.setFileSize(new BigDecimal(fileSizes).doubleValue());
            fileUpload.setFileName(fileName);
            fileUpload.setFileType(fileType);
            fileUpload.setFileContentType(contentType);
            fileUpload.setStorageType("1");//本地存储
            fileUpload.setFilePath(visitFileUrl);
            fileUpload.setFileKey(newFileName);

            fileUpload.setCreateBy(AuthUtils.getUsername());
            fileUpload.setCreateTime(new Date());

            baseMapper.insert(fileUpload);
            if (fileUpload == null) {
                throw new BusinessException( "文件上传失败");
            }

            return Convert.convert(FileDto.class, fileUpload);
        }catch (Exception e) {
            log.error("文件上传失败", e);
            e.printStackTrace();
            throw new BusinessException("文件上传失败");
        }finally {
            // 关闭文件流
            IoUtil.close(inputStream);
            IoUtil.close(fi);
        }
    }


    public static String genarateNewFileName(String fileName) {
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        return UUID.randomUUID().toString().replaceAll("-", "") + "." + suffix;
    }

    public String getNameWithoutExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf(".");
        return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
    }

    @Override
    public String findFileNameByPath(String filePath){
        log.info("findFileNameByPath() filePaht:{}",filePath);
        LambdaQueryWrapper<FileUpload> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FileUpload::getFilePath, filePath);
        FileUpload fileUpload = baseMapper.selectOne(queryWrapper);
        if(ObjectUtil.isEmpty(fileUpload)){
            throw new BusinessException("文件不存在～");
        }
        return fileUpload.getFileName();
    }


}

